#pragma once

/*--------------------------------------------------------------------------*/

struct EQuadLocation
{
	enum Enum
	{
	    First = 0,
	    Top = 0,
	    Bottom,
	    Left,
	    Right,
	    Far,
	    Near,
	    Last = Near,
	};
};

struct EQuadPosition
{
	enum Enum
	{
	    NN = 0,
	    NP,
	    PN,
	    PP,
	    Ignore
	};
};

struct EQuadPreparations
{
	enum Phase
	{
	    _1_PrepareMyData = 0,
	    _11_WaitForAsync,
	    _2_TransferMyData,
	    _3_WaitForChildrenOrder,
	    _4_PrepareChildrenData,
	    _5_AllPrepared
	};
};

struct QuadData
{
	glm::vec3*		m_positions;
	glm::vec3*		m_normals;
	glm::vec2*		m_texcoords;
	glm::vec4*		m_additionaldata;
	float*			m_heights;
	uint*	m_indices;

	QuadData() :
		m_positions(NULL),
		m_normals(NULL),
		m_texcoords(NULL),
		m_indices(NULL),
		m_additionaldata(NULL),
		m_heights(NULL)
	{}
};
/*--------------------------------------------------------------------------*/
class CelestialPlanet;

struct QuadCreation
{
	EQuadLocation::Enum		m_quadLocation;
	EQuadPosition::Enum		m_quadPosition;
	glm::vec2				m_location;
	glm::vec2				m_size;
	CelestialPlanet*		m_planet;
	uint			m_depth;

	QuadCreation() :
		m_quadLocation(EQuadLocation::Left),
		m_location(glm::vec2()),
		m_size(glm::vec2(1.0f, 1.0f)),
		m_planet(NULL),
		m_quadPosition(EQuadPosition::Ignore),
		m_depth(0)
	{}
};

/*--------------------------------------------------------------------------*/

//#define DEBUG_QUADS 1

class CelestialPlanetQuad:
	public IRenderableObject,
	public IAsyncCalc
{
public:
	CelestialPlanetQuad(const NodeCreation& nc, const QuadCreation& qc);
	~CelestialPlanetQuad();

	void RenderableBinder(uint treeCalcFlags);
	void RenderableHelper(const uint i, ERenderQuality::Type quality, uint pendingInstances);

	uint OnAsyccCalc(uint arg);
	void OnAsyncReady(uint arg);

	void OnPreCalc(uint arg);

	glm::vec2 GetCubeLocation();
	EQuadPreparations::Phase GetPhase();
private:
	CelestialPlanetQuad*		m_childs[4];
	EQuadPreparations::Phase	m_childrenPhase;
	QuadData					m_data;
	QuadCreation				m_creation;
	GLVertexArray*				m_vao;

	static uint			quadID;

	void CalculateQuad();
	void TransferToGPU();
	void PrepareChildren();
};

